package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Slf4j
@Service
public class SysDepartmentServiceImpl implements SysDepartmentService {


    @Autowired
    SysDepartmentMapper departmentMapper;


    @Override
    public List<SysDepartmentDTO> queryDepartmentList() {
        List<SysDepartmentDTO> departmentDTOList = this.queryChildrenDepartmentList(0L);

        return departmentDTOList;
    }

    @Override
    public List<Long> queryDepartmentIds() {
        LambdaQueryWrapper<SysDepartment> departmentQw = new LambdaQueryWrapper<>();
        departmentQw.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentQw.eq(SysDepartment::getParentId, 0);

        List<SysDepartment> departmentList = departmentMapper.selectList(departmentQw);

        if(CollectionUtil.isNotEmpty(departmentList)){
            List<Long> ids = departmentList.stream().map(department -> {
                return department.getId();
            }).collect(Collectors.toList());
            return ids;
        }

        return new ArrayList<>();
    }

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long departmentId, Integer includeMember) {
        if(departmentId == null || includeMember == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOS = new ArrayList<>();


        //查询该部门下对应的子部门信息
        LambdaQueryWrapper<SysDepartment> departmentQw = new LambdaQueryWrapper<>();
        departmentQw.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentQw.eq(SysDepartment::getParentId, departmentId);

        List<SysDepartment> departmentList = departmentMapper.selectList(departmentQw);
        if(CollectionUtil.isNotEmpty(departmentList)){
            for (SysDepartment department : departmentList) {
                DepartmentOrUserSimpleDTO departmentDTO = new DepartmentOrUserSimpleDTO();
                departmentDTO.setId(department.getId());
                departmentDTO.setName(department.getName());
                departmentDTO.setType(1);

                //添加到返回值对象中
                departmentOrUserSimpleDTOS.add(departmentDTO);
            }
        }

        //includeMember = 0 说明包含员工， 查询员工信息
        if (includeMember == 0) {
            LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
            companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            companyUserQw.eq(SysCompanyUser::getDepartmentId, departmentId);

            List<SysCompanyUser> companyUserList = companyUserMapper.selectList(companyUserQw);
            if(CollectionUtil.isNotEmpty(companyUserList)){
                for (SysCompanyUser companyUser : companyUserList) {
                    DepartmentOrUserSimpleDTO userDto = new DepartmentOrUserSimpleDTO();
                    userDto.setId(companyUser.getId());
                    userDto.setName(companyUser.getUserName());
                    userDto.setType(2);
                    //添加到返回值对象中
                    departmentOrUserSimpleDTOS.add(userDto);
                }
            }
        }

        return departmentOrUserSimpleDTOS;
    }

    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {

        //定义返回值集合
        List<Long> list  = new ArrayList<>();

        SysCompanyUser companyUser = companyUserMapper.selectById(companyUserId);
        //员工所在的部门id
        Long departmentId = companyUser.getDepartmentId();
        if(departmentId != null){
            list.add(departmentId);
        }
        Long parentId = departmentId;
        while (true){
            //获取该部门的上级部门id
            if(parentId != null){
                //根据部门id获取部门对象
                SysDepartment department = departmentMapper.selectById(parentId);
                //获取部门上级id
                parentId = department.getParentId();
                //如果上级id为0 ，说明是顶级部门
                if(parentId == 0){
                    break;
                }
                list.add(parentId);
            }
        }



        return list;
    }

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    public List<SysDepartmentDTO> queryChildrenDepartmentList(Long parentId){
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId, parentId);
        //查询部门列表
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(departmentList)){
            List<SysDepartmentDTO> departmentDTOList = BeanHelper.copyWithCollection(departmentList, SysDepartmentDTO.class);
            //parementId = 0, 查询到的是一级部门，循环一级部门
            for (SysDepartmentDTO department : departmentDTOList) {
                //查询子部门
                List<SysDepartmentDTO> childrenDepartment = this.queryChildrenDepartmentList(department.getId());
                if(CollectionUtil.isNotEmpty(childrenDepartment)){
                    department.setChildren(childrenDepartment);
                } else{
                    department.setChildren(new ArrayList<>());
                }
            }
            return departmentDTOList;
        }
        return new ArrayList<>();

    }
}
